package com.poposchool.project.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.poposchool.project.common.Constants;
import com.poposchool.project.common.Result;
import com.poposchool.project.entity.Files;
import com.poposchool.project.service.FilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Author Wang Jie
 * @Date 2022/6/30 12:25
 * @Version 1.0
 */


/**
 * 文件上传相关接口
 */
@RestController
@RequestMapping("/file")
public class FileController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Resource
    FilesService filesService;

    @Value("${files.upload.path}")
    private String fileUploadPath;



    @PostMapping("/upload")
    public Result upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename);
        long size = file.getSize();
        //先存储到磁盘上面
        File uploadFile = new File(fileUploadPath);
        if (!uploadFile.exists()) {
            //创建一个新的目录
            uploadFile.mkdirs();
        }
        //定义一个文件的标识码
        String simpleUUID = IdUtil.fastSimpleUUID();
        //加上文件类型
        String fileUUID = simpleUUID + StrUtil.DOT + type;
        String url;
        //要存储的文件
        File uploadFileELe = new File(fileUploadPath + fileUUID);
        //获取文件的md5,解决图片一样占用资源的情况
        String md5 = SecureUtil.md5(file.getInputStream());
        Files fileCountSameMd5 = filesService.getFileMd5(md5);
        if (fileCountSameMd5 != null) {//证明有相同的文件,多个文件对一一个相同的文件
            url = fileCountSameMd5.getUrl();
        } else {
            //上传文件
            file.transferTo(uploadFileELe);
//            url = "http://121.40.54.171:9090/file/"+fileUUID;
            url = "http://localhost:9090/file/" + fileUUID;
        }

        //存到数据库中
        Files files = new Files();
        files.setFileName(originalFilename);
        files.setType(type);
        files.setSize(size / 1024);//kb
        files.setUrl(url);
        files.setMd5(md5);
        files.setEnable(false);
        filesService.insert(files);
        //用对象回，不然json转化异常
        //删除缓存对象，实现刷新,性能比较低
        deleteRedisFile(Constants.FILES_ALL);
        //有几种刷新redis的方式，比如取出redis的缓存，然后加入对应数据，然后再放进去就ok了。
        return Result.success(url);
    }

    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        File uploadFile = new File(fileUploadPath + fileUUID);
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();

    }

    @GetMapping("/pageFiles")
    public Map<String,Object> getPage(
            @RequestParam(name = "pageNum",defaultValue = "1") Integer pageNum,
            @RequestParam(name = "pageSize",defaultValue = "6") Integer pageSize,
            @RequestParam(name = "name",defaultValue = "") String name){
        Map<String,Object> map = new HashMap<>();
//      放入总数量
        map.put("total",filesService.getAllCount());
//      多条件查询
        map.put("files",filesService.getPageFiles(pageNum,pageSize,name));
        return map;
    }


    @PostMapping("/batchDeleteFiles")
//    参数类型不对，@RequestBody 后面用Map或者是javabean
    public void batchDeleteUsers(@RequestBody Map<String, List<Integer>> ids){
        if (ids.get("ids").size() == 0){
            return;
        }
        filesService.batchDeleteFiles(ids.get("ids"));
        deleteRedisFile(Constants.FILES_ALL);
    }

    @DeleteMapping("/deleteFile")
    public void deleteUser(Integer id){
        filesService.deleteFile(id);
        deleteRedisFile(Constants.FILES_ALL);
    }

    @GetMapping("/updateEnable")
    public void updateEnable(@RequestParam("id") Integer id,@RequestParam("enable") Boolean enable){
        filesService.updateEnable(id,enable);
        deleteRedisFile(Constants.FILES_ALL);
    }


    @GetMapping("/getEnableFile")
    public Result getEnableFile(){
        String jsonStr = redisTemplate.opsForValue().get(Constants.FILES_ALL);
        List<String> list;
        if (StrUtil.isBlank(jsonStr)){
            list = filesService.getEnableFile();
            //缓存到redis中
            redisTemplate.opsForValue().set(Constants.FILES_ALL,JSONUtil.toJsonStr(list));
        }else {
            //吧string转化成字符串
            list = JSONUtil.toBean(jsonStr, new TypeReference<List<String>>() {
            },true);
        }

        return Result.success(list);
    }

    //删除缓存
    public void deleteRedisFile(String redisKey){
        redisTemplate.delete(redisKey);
    }
}
